package com.wayne.blog.aspect;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * 日志切面
 * @author Lang
 * @since 2024/06/06
 */
@Aspect
@Component
public class LogAspect {
    private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Around("execution(* com.wayne.blog.controller.*.*(..))")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        Object result = point.proceed();
        long time = System.currentTimeMillis() - beginTime;

        try {
            recordLog(point, time);
        } catch (Exception e) {
            logger.error("记录接口日志失败", e);
        }

        return result;
    }

    private void recordLog(ProceedingJoinPoint point, long time) throws Exception {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            return;
        }

        HttpServletRequest request = attributes.getRequest();
        MethodSignature signature = (MethodSignature) point.getSignature();
        String className = signature.getDeclaringTypeName();
        String methodName = signature.getName();

        // 获取请求参数
        Map<String, String[]> params = request.getParameterMap();
        String urlParams = objectMapper.writeValueAsString(params);

        // 构建日志内容
        StringBuilder logContent = new StringBuilder();
        logContent.append("Lang-common request report ---------").append(getCurrentTime()).append(" --------------------------\n");
        logContent.append("Url         : ").append(request.getMethod()).append("  ").append(request.getRequestURI()).append("\n");
        logContent.append("Controller  : ").append(className).append(".(").append(signature.getDeclaringType().getSimpleName()).append(".java:1)\n");
        logContent.append("Method      : ").append(methodName).append("\n");
        logContent.append("UrlPara     : ").append(urlParams).append("\n");
        logContent.append("----------------------------------------------------------------------------------");

        logger.info(logContent.toString());
    }

    private String getCurrentTime() {
        return java.time.LocalDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
} 